package org.smile.util;

import org.smile.commons.ExceptionUtils;
import org.smile.commons.SmileRunException;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Set;

public class NetworkUtils {
    /**
     * 获取本地MAC地址
     *
     * @return
     */
    public static String getLocalMac() {
        InetAddress ia;
        byte[] mac = null;
        try {
            // 获取本地IP对象
            ia = InetAddress.getLocalHost();
            // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
            mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
        } catch (Exception e) {
            throw new SmileRunException(ExceptionUtils.getExceptionMsg(e));
        }

        return convertToMac(mac);
    }

    /**
     * 转化为物理地址字符串
     *
     * @param mac
     * @return
     */
    private static String convertToMac(byte[] mac) {
        // 下面代码是把mac地址拼装成String
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        return sb.toString();
    }

    /**
     * 本地ip
     */
    public static String getLocalIp() {
        try {
            InetAddress addr = InetAddress.getLocalHost();
            return addr.getHostAddress();
        } catch (UnknownHostException e) {
            throw new SmileRunException("get local ip error", e);
        }
    }

    /**
     * 获取本地物理地址从鼐
     *
     * @return
     */
    public static Set<String> getLocalMacs(boolean needUse) {
        Set<String> macs = new LinkedHashSet<>();
        // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
        Enumeration<NetworkInterface> interfaces = null;
        try {
            interfaces = NetworkInterface.getNetworkInterfaces();
            while (interfaces.hasMoreElements()) {
                NetworkInterface ni = interfaces.nextElement();
                if(((needUse&&ni.isUp())||!needUse)&&!ni.isVirtual()) {
                    byte[] bytes = new byte[0];
                    try {
                        bytes = ni.getHardwareAddress();
                        if (bytes != null) {
                            String mac = convertToMac(bytes);
                            macs.add(mac);
                        }
                    } catch (SocketException e) {
                        //do nothing
                    }
                }
            }
        } catch (SocketException e) {
            throw new SmileRunException(e);
        }
        return macs;
    }

    /**
     *
     * @return
     */
    public static Set<String> getLocalMacs() {
        return getLocalMacs(true);
    }

    /**
     * 获取IP
     * @param intf
     * @return
     */
    public static String getAddressIp(NetworkInterface intf){
        Enumeration<InetAddress> enumeration= intf.getInetAddresses();
        while(enumeration.hasMoreElements()){
            InetAddress address=enumeration.nextElement();
            byte[] bytes=address.getAddress();
            if(bytes!=null){
                return  address.getHostAddress();
            }
        }
        return null;
    }

}
